﻿using Hangfire;
using Microsoft.AspNetCore.HttpOverrides;
using RazorEngineCore;
using SimpleX.Tracing;

namespace SimpleX
{
    public static class WebApplication
    {
        public static void Run(string[] args,
            Action<IServiceCollection> beforeBuild = null,
            Action afterBuild = null)
        {
            var builder = Microsoft.AspNetCore.Builder.WebApplication.CreateBuilder(args);

            //初始化
            App.Configuration = builder.Configuration;
            App.ExecuteOnConfiguration();

            builder.Configuration.AddJsonFile();
            builder.Logging.ClearProviders();
            builder.Host.UseNLog();
            builder.Services.AddHttpContextAccessor();

            //系统生成RSA公钥和私钥
            PwdUtils.GenerateRsaKeys();

            //Services扩展
            var services = builder.Services;

            //IP获取
            services.Configure<ForwardedHeadersOptions>(options =>
            {
                options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
                //仅允许受信任的代理和网络转接头。否则，可能会受到 IP 欺骗攻击 安全起见推荐白名单:options.KnownProxies.Add(IPAddress.Parse("10.32.44.157"));
                options.KnownProxies.Clear();
            });

            services.AddCors(); //跨域
            services.AddInjectAssembly();//自动注入
            services.AddControllers();// AddControllers 和 Json配置
            services.AddJwt();//Jwt
            services.AddSwagger();//Swagger
            services.AddCache();//缓存
            services.AddFluent();//验证
            services.AddCAP(); //CAP 内存
            services.AddTransient<IRazorEngine, RazorEngine>();//模板引擎
            services.AddHangfire(x => x.UseInMemoryStorage()); //定时调度
            services.AddHangfireServer(option =>
            {
                option.SchedulePollingInterval = TimeSpan.FromMilliseconds(1000);
                option.HeartbeatInterval = TimeSpan.FromMilliseconds(1000);
                option.WorkerCount = Math.Max(Environment.ProcessorCount, 10);
            });

            services.AddTracingServices("SimpleX");//埋点服务

            beforeBuild?.Invoke(services);

            var app = builder.Build();

            app.UseTracing();
            app.UseForwardedHeaders();
            app.UseSwagger();
            app.UseMiddleware<RealIPMiddleware>();//Real-IP
            app.UseMiddleware<UnifyResultStopwatchMiddleware>();
            app.UseMiddleware<RequestMiddleware>();
            app.UseCors();
            app.UseAuthorization();
            app.MapControllers();

            app.UseWebSockets(new WebSocketOptions
            {
                KeepAliveInterval = TimeSpan.FromSeconds(60),
            });

            app.UseMiddleware<WebsocketHandlerMiddleware>();
            app.UseHangfireDashboard("/simplehf");

            App.ServiceProvider = app.Services;
            App.WebHostEnvironment = app.Environment;

            SqlSugarCodeFirst.Execute();//CodeFirst

            afterBuild?.Invoke();

            app.Run();
        }
    }
}